<?php

/**
 * 抽奖发礼包
 * Date: 2018/11/21
 */

namespace Lib\Paas;

use Lib\Base\Request;
use Lib\Base\Validate;
use Lib\Db\Query;

class Lottery extends Base
{
    private $sendType;
    public function __construct($data = [])
    {
        parent::__construct($data);
    }

    /**
     * 抽奖
     * @param array $lotteryInfo =
     * [
     *      'MRMSID' =>'【必填】礼包单号'
     *      'iPackageGroupId' =>'【选填】（iPackageGroupId和iPackageGroupIdList二选一）礼包组ID',
     *      'iPackageGroupIdList' => '【选填】（iPackageGroupId和iPackageGroupIdList二选一）礼包组连抽信息,格式：礼包组ID1,发送数量:抽奖次数@@礼包组ID2,发送数量:抽奖次数@@...',
     *      'iPackageNum' => '【选填】 礼包组数量，默认1',
     *      'sGameOpenid' => '【选填】游戏openid(默认取当前登录账号的openid)，给非当前登录用户的角色发货时传递该值',
     *      'area' =>'【必填】服务器ID（或者手游渠道：手Q、微信)',
     *      'platId' =>'【如果业务区分平台则必填，否则选填】手机操作系统（iOS：0、安卓：1）',
     *      'partition' =>'【如果业务区分区服则必填，否则选填】小区ID',
     *      'roleId' =>'【必填】角色ID',
     *      'roleName' =>'【选填】角色昵称，编码方式：urlencode，编码：utf8',
     *      'checkparam' =>'【必填】角色信息，可以通过Role\getRoleInfo()函数获取',
     *      'checkstr' =>'【必填】角色签名，可以通过Role\getRoleInfo()函数获取',
     *]
     * @return array 抽奖结果信息
     * [
     *      'iRet'=>'0 发货成功。-1 发货失败，回滚资格。-2 发货失败，不回滚资格',
     *      'sMsg'=>'系统消息',
     *      'data' => [
     *          'iPackageGroupId'=>'成功发货的礼包组ID',
     *          'iPackageId'=>'成功发货的礼包ID',
     *          'sPackageName'=>'成功发货的礼包名称',
     *          'iPackageNum'=>'成功发货的礼包数量',
     *          'sPackageCDkey'=>'CDK',
     *          'dTimeNow' =>'成功发货的时间'
     *      ]
     * ]
     */
    public function doLottery($lotteryInfo)
    {
        if (!isset($lotteryInfo['iPackageNum'])) {
            $lotteryInfo['iPackageNum'] = 1;
        }

        $checkRet = $this->checkLotteryParam($lotteryInfo);
        if ($checkRet['iRet'] != '0') {
            return $checkRet;
        }

        //将暂存箱中的物品发送到游戏账户（掉IDIP发货，但不记录发货流水）
        if ($this->sendType === 2) {
            $lotteryInfo['iSendType'] = '2';
        }

        //组合URL
        $url = $this->getPaasRequestUrl('resource.mrms', $lotteryInfo);

        $res = $this->http->get($url);

        recordLog('抽奖接口返回结果：' . var_export($res, true), __FILE__, __LINE__);

        //curl请求paas接口异常
        if ($res["ret"] != 0) {
            $this->tglogReport('框架请求ULink-Paas出现异常，curl_errno：' . $res['ret'] . '，curl_error：' . $res['msg'], 'resource.mrms');
            if ($res["ret"] == '28') {
                //请求pass接口超时，记录发货失败信息到DB
                $this->saveLotteryLog(-1, 'app curl paas timeout', $lotteryInfo);
                return $this->getRetData('-2', '系统繁忙，请稍后再试[' . __LINE__ . ']！', ['timeout' => '1']); // 不用回滚资格
            } else {
                //curl超时以外的其他报错，说明paas接口请求失败，回滚用户资格
                return $this->getRetData('-1', '系统繁忙，请稍后再试[' . __LINE__ . ']！', ['timeout' => '0']);
            }
        }
        $res = $res['data'];

        //curl请求paas正常，但是paas调mrms超时，记录发货失败信息到DB，不回滚资格
        if ($res["ret"] == '-99999') {
            $this->saveLotteryLog(-2, 'paas curl mrms timeout', $lotteryInfo);
            return $this->getRetData('-2', '系统繁忙，请稍后再试[' . __LINE__ . ']！', ['timeout' => '1']); // 不用回滚资格
        }

        $rtnData['timeout'] = 0;
        $rtnData['sPaasSerial'] = $res['sSerial'];

        if ($res["ret"] != 0) {
            //curl请求paas正常，但是paas接口返回异常（paas接口还没有请求mrms接口发货，一些校验信息失败），发货失败，回滚资格
            return $this->getRetData('-1', '系统繁忙，请稍后再试[' . __LINE__ . ']！', $rtnData);
        } else if ($res["data"]["iRet"] == '0') {
            // 发货成功
            $rtnData['data'] = [
                'iPackageGroupId' => $res['data']['iPackageGroupId'],
                'iPackageId' => $res['data']['iPackageId'],
                'sPackageName' => $res['data']['sPackageName'],
                'iPackageNum' => $res['data']['iPackageNum'],
                'sPackageCDkey' => $res['data']['sPackageCDkey'],
                'dTimeNow' => $res['data']['dTimeNow'],
            ];
            return $this->getRetData(0, 'success', $rtnData);
        } else if ($res["data"]["iRet"] > -100000 && $res["data"]["iRet"] < 0) {
            //curl请求paas正常，paas请求mrms正常，mrms返回发货失败，根据mrms错误码确认需要回滚资格
            return $this->getRetData('-1', '系统繁忙，请稍后再试[' . __LINE__ . ']！', $rtnData);
        } else {
            //curl请求paas正常，paas请求mrms正常，mrms返回发货失败，根据mrms错误码确认不需要回滚资格
            return $this->getRetData('-2', '系统繁忙，请稍后再试[' . __LINE__ . ']！', $rtnData);
        }
    }

    /**
     * 扣资格发货到暂存箱（物品实际还没有发送到用户账户）
     * @param array $lotteryParam 礼包和角色信息，参考lotteryQualTrans方法的$lotteryParam参数
     * @param array $qualParam 资格信息，参考lotteryQualTrans方法的$qualParam参数
     * @param int $sendType 发货类型：1-只记流水IDIP不发货; 2-只IDIP发货不记流水
     * @param array $pubQualParam 公共资格信息，参考lotteryQualTrans方法的$pubQualParam参数
     * @return array 抽奖结果信息，参考lotteryQualTrans的返回结果
     */
    public function lotteryQualTransToBox($lotteryParam, $qualParam, $pubQualParam = [])
    {
        $this->sendType = 1;
        $ret = $this->lotteryQualTrans($lotteryParam, $qualParam, $pubQualParam);
        $this->sendType = 0;
        return $ret;
    }

    /**
     * 扣积分发货到暂存箱（物品实际还没有发送到用户账户）
     * @param array $lotteryParam 礼包和角色信息，参考lotteryPointTrans方法的$lotteryParam参数
     * @param array $pointParam  积分信息，参考lotteryPointTrans方法的$pointParam参数
     * @return array 抽奖结果信息，参考lotteryPointTrans方法的返回结果
     */
    public function lotteryPointTransToBox($lotteryParam, $pointParam)
    {
        $this->sendType = 1;
        $ret =  $this->lotteryPointTrans($lotteryParam, $pointParam);
        $this->sendType = 0;
        return $ret;
    }

    /**
     * 将暂存箱中的物品发送到游戏账户
     * @param array $lotteryInfo =
     * [
     *      'MRMSID' =>'【必填】礼包单号',
     *      'iId' => '【必填】调用发货到暂存箱相关方法是返回的发货流水ID（取结果集中的iId），多个ID用逗号隔开：id1,id2,id3...',
     *      'iPackageId' => '【必填】要发送的礼包ID，必须是已经发货到暂存箱中的礼包',
     *      'iPackageGroupId' =>'【选填】（iPackageGroupId和iPackageGroupIdList二选一）礼包组ID',
     *      'iPackageGroupIdList' => '【选填】（iPackageGroupId和iPackageGroupIdList二选一）礼包组连抽信息,格式：礼包组ID1,发送数量:抽奖次数@@礼包组ID2,发送数量:抽奖次数@@...',
     *      'iPackageNum' => '【选填】 礼包组数量，默认1',
     *      'sGameOpenid' => '【选填】游戏openid(默认取当前登录账号的openid)，给非当前登录用户的角色发货时传递该值',
     *      'area' =>'【必填】服务器ID（或者手游渠道：手Q、微信)',
     *      'platId' =>'【如果业务区分平台则必填，否则选填】手机操作系统（iOS：0、安卓：1）',
     *      'partition' =>'【如果业务区分区服则必填，否则选填】小区ID',
     *      'roleId' =>'【必填】角色ID',
     *      'roleName' =>'【选填】角色昵称，编码方式：urlencode，编码：utf8',
     *      'checkparam' =>'【必填】角色信息，可以通过Role\getRoleInfo()函数获取',
     *      'checkstr' =>'【必填】角色签名，可以通过Role\getRoleInfo()函数获取',
     *]
     *
     * @return array 发货结果，参考doLottery方法的返回结果
     */
    public function sendBoxPackageToGame($lotteryInfo)
    {
        if (!preg_match("/^(\d+\,?)+$/", $lotteryInfo['iId'])) {
            return ['iRet' => '-2', 'sMsg' => '发货流水ID必须整数，多个ID用英文逗号隔开！', 'data' => []];
        }

        if (!Validate::checkNaturalNum($lotteryInfo['iPackageId'])) {
            return ['iRet' => '-2', 'sMsg' => '礼包ID必须为整数！', 'data' => []];
        }

        $this->sendType = 2;
        $ret =  $this->doLottery($lotteryInfo);
        $this->sendType = 0;
        return $ret;
    }

    /**
     * 查询中奖记录
     * @param string $mrmsId【必填】 礼包单号，必须传
     * @param int $curPage【选填】 要查询第几页的数据（分页查询时用到，默认查询第一页）
     * @param int $pageSize【选填】 没有查询的记录数（分页查询时用到，默认一次查询10条）
     * @param string $sPackageId【选填】 查询指定的礼包ID的中奖纪录（多个礼包ID逗号分隔）
     * @param string $sExcludePackageId【选填】 查询时排除指定的礼包ID的中奖纪录（多个礼包ID逗号分隔）
     * @param array $extendData 【选填】其他扩展参数，目前支持的参数列表如下（根据实际需要传递相关参数，如果传递多个值，则查询查询满足所有条件的中奖记录）
     * [
     *      'area' => '查询指定渠道获奖记录',
     *      'platId' => '查询指定平台获奖记录',
     *      'partition' => '查询指定区服的获奖记录',
     *      'roleId' => '查询指定角色的获奖记录',
     *      'sExtend1' => '根据抽中奖励时存储的扩展信息1来查询',
     *      'sExtend2' => '根据抽中奖励时存储的扩展信息2来查询',
     *      'sExtend3' => '根据抽中奖励时存储的扩展信息3来查询',
     *      'sExtend4' => '根据抽中奖励时存储的扩展信息4来查询',
     *      'sExtend5' => '根据抽中奖励时存储的扩展信息5来查询',
     * ]
     *
     * @return array
     * [
     *      'iRet' => '返回码',
     *      'sMsg' => '系统消息',
     *      'jData' => [],      //要查询的礼包等信息
     *      'myGiftList' =>[],  //中奖礼包信息
     *      'pageNow' => '当前页码',
     *      'pageTotal' => '总页数'
     *      'nTotal' => '礼包总数'
     *  ]
     */
    public function getLotteryInfo($mrmsId, $curPage = 1, $pageSize = 10, $sPackageId = '', $sExcludePackageId = '', $extendData = [])
    {
        if (!Validate::checkMRMSID($mrmsId)) {
            return $this->getRetData('-1000600', '礼包单号不能为空！');
        }

        if (!Validate::checkNaturalNum($curPage)) {
            return $this->getRetData('-1000601', '当前查询数据页码错误！');
        }

        if (!Validate::checkNaturalNum($pageSize)) {
            return $this->getRetData('-1000602', '每页返回结果记录数参数错误！');
        }

        if ($sPackageId != '') {
            $pkgIds = explode(',', $sPackageId);
            foreach ($pkgIds as $id) {
                if (!Validate::checkNaturalNum($id)) {
                    return $this->getRetData('-1000603', '要查询的礼包ID错误！');
                }
            }
        }

        if ($sExcludePackageId != '') {
            $elPkgIds = explode(',', $sExcludePackageId);
            foreach ($elPkgIds as $id) {
                if (!Validate::checkNaturalNum($id)) {
                    return $this->getRetData('-1000604', '查询时要排除的礼包ID错误！');
                }
            }
        }

        if (isset($extendData['area']) && !Validate::checkArea($extendData['area'])) {
            return $this->getRetData('-1000650', '渠道ID错误！');
        }

        if (isset($extendData['platId']) && !Validate::checkPlat($extendData['platId'])) {
            return $this->getRetData('-1000651', '平台ID错误！');
        }

        if (isset($extendData['partition']) && !Validate::checkPartition($extendData['partition'])) {
            return $this->getRetData('-1000652', '区服ID错误！');
        }

        if (isset($extendData['roleId']) && !Validate::checkRoleId($extendData['roleId'])) {
            return $this->getRetData('-1000653', '角色ID错误！');
        }

        $paasParam = ['MRMSID' => $mrmsId, 'iPageNow' => intval($curPage), 'iPageSize' => intval($pageSize), 'iPackageId' => $sPackageId, 'iExcludePackageId' => $sExcludePackageId];
        //组合URL
        $paasParam = array_merge($paasParam, $extendData);
        $url = $this->getPaasRequestUrl('lottery.info', $paasParam);
        $res = $this->http->get($url);
        recordLog("lotteryinfo paas result：" . \var_export($res, true), __FILE__, __LINE__);

        if ($res['ret'] != 0) {
            $this->tglogReport('框架请求ULink-Paas出现异常，curl_errno：' . $res['ret'] . '，curl_error：' . $res['msg'], 'lottery.info');
            return $this->getRetData(CURL_ERROR_NO, '系统繁忙，请稍后再试！');
        }
        $res = $res['data'];

        if ($res['ret'] != 0 || $res['data']['iRet'] != 0) {
            $iRet = $res['ret'] != 0 ? $res['ret'] : $res['data']['iRet'];
            return $this->getRetData($iRet, '系统繁忙，请稍后再试！');
        } else {
            return $res['data'];
        }
    }

    /**
     * 扣除资格+发货（事务）,应用程序不需要进行资格控制以及资格回滚等，每次发货，直接请求该接口即可
     *
     * @param array $lotteryParam 礼包和角色信息
     * [
     *      'MRMSID' =>'【必填】礼包单号'
     *      'iPackageGroupId' =>'【选填】（iPackageGroupId和iPackageGroupIdList二选一）礼包组ID',
     *      'iPackageGroupIdList' => '【选填】（iPackageGroupId和iPackageGroupIdList二选一）礼包组连抽信息,格式：礼包组ID1,发送数量:抽奖次数@@礼包组ID2,发送数量:抽奖次数@@...',
     *      'iPackageNum' => '【选填】 礼包组数量，默认1',
     *      'sGameOpenid' => '【选填】游戏openid(默认取当前登录账号的openid)，给非当前登录用户的角色发货时传递该值',
     *      'area' =>'【必填】服务器ID（或者手游渠道：手Q、微信)',
     *      'platId' =>'【如果业务区分平台则必填，否则选填】手机操作系统（iOS：0、安卓：1）',
     *      'partition' =>'【如果业务区分区服则必填，否则选填】小区ID',
     *      'roleId' =>'【必填】角色ID',
     *      'roleName' =>'【选填】角色昵称，编码方式：urlencode，编码：utf8',
     *      'checkparam' =>'【必填】角色信息，可以通过Role\getRoleInfo()函数获取',
     *      'checkstr' =>'【必填】角色签名，可以通过Role\getRoleInfo()函数获取',
     *]
     * @param array $qualParam 资格信息
     * [
     *      'qualKey' => '【必填】用于资格控制的key(必须唯一)，不要加openid，paas接口会自动加上openid',
     *      'limitNum' =>'【必填】周期内可以获得的总资格',
     *      'limitType' => '【必填】A|D|Z|M  A-整个活动期间，D-以天为周期性资格，Z-以自然周为周期性资格，M-以自然月为周期性资格'
     *      'cycleNum' =>'【limitType参数不为A时必填，为A时该值无意义】limitType对应的周期长度'
     *      'usePerTime' => '【选填】每次使用需要扣除的数量，默认扣除1',
     * ]
     *
     * 例如：
     * $qualParam['qualKey'=>'test1', 'limitNum'=>'1', 'limitType'=>'A'] 表示整个活动期间获得1次资格
     * $qualParam['qualKey'=>'test1', 'limitNum'=>'1', 'limitType'=>'D', 'cycleNum'=>'2'] 表示以每2天为一个周期，每个周期（每2天）获得1次资格
     * $qualParam['qualKey'=>'test1', 'limitNum'=>'2', 'limitType'=>'D', 'cycleNum'=>'1'] 表示以每1天为一个周期，每个周期（每1天）获得2次资格
     * $qualParam['qualKey'=>'test1', 'limitNum'=>'2', 'limitType'=>'Z', 'cycleNum'=>'1'] 表示以每1自然周为一个周期，每个周期（每1个自然周）获得2次资格
     * $qualParam['qualKey'=>'test1', 'limitNum'=>'1', 'limitType'=>'M', 'cycleNum'=>'3'] 表示以每3自然月为一个周期，每个周期（每3个自然月）获得1次资格
     *
     * @param array $pubQualParam 【选填】公共资格信息，默认空数组
     * [
     *      'qualKey' => '【必填】用于资格控制的key(必须唯一)，不要加openid，paas接口会自动加上openid',
     *      'limitNum' =>'【必填】周期内可以获得的总资格',
     *      'limitType' => '【必填】A|D|Z|M  A-整个活动期间，D-以天为周期性资格，Z-以自然周为周期性资格，M-以自然月为周期性资格'
     *      'cycleNum' =>'【limitType参数不为A时必填，为A时该值无意义】limitType对应的周期长度'
     *      'usePerTime' => '【选填】每次使用需要扣除的数量，默认扣除1',
     * ]
     *
     * 使用场景：
     * 抽奖限制每天1次，活动期间总限制5次。就可以通过$pubQualParam参数来控制
     * $qualParam = ['qualKey'=>'lottery_login_day', 'limitNum'=>'1', 'limitType'=>'D', 'cycleNum'=>'1']
     * $pubQualParam = ['qualKey'=>'lottery_login_total', 'limitNum'=>'5', 'limitType'=>'A']
     *
     *
     * @return array 抽奖结果信息
     * [
     *      'iRet'=>'=0，请求成功，!=0 请求失败',
     *      'sMsg'=>'系统消息',
     *      'data' => [
     *          'iPackageGroupId'=>'成功发货的礼包组ID',
     *          'iPackageId'=>'成功发货的礼包ID',
     *          'sPackageName'=>'成功发货的礼包名称',
     *          'iPackageNum'=>'成功发货的礼包数量',
     *          'sPackageCDkey'=>'CDK',
     *          'dTimeNow' =>'成功发货的时间'
     *      ],
     *      'originalData' =>[],   //发货接口返回的全部数据
     * ]
     */
    public function lotteryQualTrans($lotteryParam, $qualParam, $pubQualParam = [])
    {
        if (!is_array($lotteryParam) || !is_array($qualParam) || !is_array($pubQualParam)) {
            return $this->getRetData('-1000628', '参数错误！', ['timeout' => 0]);
        }

        if (!isset($lotteryParam['iPackageNum'])) {
            $lotteryParam['iPackageNum'] = 1;
        }
        $checkRet = $this->checkLotteryParam($lotteryParam);
        if ($checkRet['iRet'] != '0') {
            return $checkRet;
        }

        //暂存箱发货
        if ($this->sendType === 1) {
            $lotteryParam['iSendType'] = '1';
        }

        if (!isset($qualParam['qualKey']) || $qualParam['qualKey'] == '') {
            return $this->getRetData('-1000605', '资格key不能为空！', ['timeout' => 0]);
        }

        if (!isset($qualParam['usePerTime']) || empty($qualParam['usePerTime'])) {
            $qualParam['usePerTime'] = 1;
        }
        if (!in_array($qualParam['limitType'], array('A', 'D', 'W', 'M', 'Z'))) {
            recordLog("limitType error：value=" . $qualParam['limitType'], __FILE__, __LINE__, LP_ERROR);
            return $this->getRetData('-1000606', '资格类型错误！', ['timeout' => 0]);
        }
        if ($qualParam['usePerTime'] > $qualParam['limitNum']) {
            recordLog("usePerTime should be smaller than limitNum!", __FILE__, __LINE__, LP_ERROR);
            return $this->getRetData('-1000607', '需要扣除的资格数错误！', ['timeout' => 0]);
        }

        $lotteryParam['sQualKey'] = $qualParam['qualKey'];

        if ($qualParam['limitType'] == 'A') {
            $lotteryParam['sLimitType'] = '1';
        } else {
            if (!isset($qualParam['cycleNum']) || !preg_match('/^[1-9]+\d*$/', $qualParam['cycleNum'])) {
                return $this->getRetData('-1000608', '周期资格数错误！', ['timeout' => 0]);
            }
            $lotteryParam['sLimitType'] = '2_' . $qualParam['limitType'] . '_' . $qualParam['cycleNum'];
        }

        $lotteryParam['iLimitNum'] = $qualParam['limitNum'];
        $lotteryParam['iUsePerTime'] = $qualParam['usePerTime'];

        if (!isset($lotteryParam['iPackageNum'])) {
            $lotteryParam['iPackageNum'] = 1;
        }

        if (isset($pubQualParam['qualKey']) && $pubQualParam['qualKey'] != '') {

            if ($pubQualParam['qualKey'] == $qualParam['qualKey']) {
                recordLog("public qualkey and private qualkey cannot be the same!", __FILE__, __LINE__, LP_ERROR);
                return $this->getRetData('-1000609', '公有资格key和私有资格key不能相同！', ['timeout' => 0]);
            }

            if (!preg_match('/^[1-9]\d*$/', $pubQualParam['limitNum'])) {
                recordLog("public qual limitNum error：value=" . $pubQualParam['limitNum'], __FILE__, __LINE__, LP_ERROR);
                return $this->getRetData('-1000610', '公有资格总数错误！', ['timeout' => 0]);
            }

            if (!isset($pubQualParam['usePerTime']) || $pubQualParam['usePerTime'] == '') {
                $pubQualParam['usePerTime'] = 1;
            }
            if (!preg_match('/^[1-9]\d*$/', $pubQualParam['usePerTime'])) {
                recordLog("public qual usePerTime error：value=" . $pubQualParam['usePerTime'], __FILE__, __LINE__, LP_ERROR);
                return $this->getRetData('-1000611', '每次扣除的公有资格数错误！', ['timeout' => 0]);
            }

            if (!in_array($pubQualParam['limitType'], array('A', 'D', 'W', 'M', 'Z'))) {
                recordLog("public qual limitType error：value=" . $pubQualParam['limitType'], __FILE__, __LINE__, LP_ERROR);
                return $this->getRetData('-1000612', '公有资格类型错误！', ['timeout' => 0]);
            }

            if ($pubQualParam['usePerTime'] > $pubQualParam['limitNum']) {
                recordLog("public qual usePerTime should be smaller than limitNum!", __FILE__, __LINE__, LP_ERROR);
                return $this->getRetData('-1000613', '需要扣除的公有资格数错误！', ['timeout' => 0]);
            }

            $lotteryParam['sPubQualKey'] = $pubQualParam['qualKey'];

            if ($pubQualParam['limitType'] == 'A') {
                $lotteryParam['sPubLimitType'] = '1';
            } else {
                if (!isset($pubQualParam['cycleNum']) || !preg_match('/^[1-9]+\d*$/', $pubQualParam['cycleNum'])) {
                    recordLog("public qual cycleNum error：value=" . $pubQualParam['cycleNum'], __FILE__, __LINE__, LP_ERROR);
                    return $this->getRetData('-1000614', '周期公有资格数错误！', ['timeout' => 0]);
                }
                $lotteryParam['sPubLimitType'] = '2_' . $pubQualParam['limitType'] . '_' . $pubQualParam['cycleNum'];
            }

            $lotteryParam['iPubLimitNum'] = $pubQualParam['limitNum'];
            $lotteryParam['iPubUsePerTime'] = $pubQualParam['usePerTime'];
        }

        //组合URL
        $url = $this->getPaasRequestUrl('lottery.trans', $lotteryParam);
        $res = $this->http->get($url);
        recordLog("lottery qual trans paas result：" . var_export($res, true), __FILE__, __LINE__);

        if ($res['ret'] != 0) {
            $this->tglogReport('框架请求ULink-Paas出现异常，curl_errno：' . $res['ret'] . '，curl_error：' . $res['msg'], 'lottery.trans');
            if ($res['ret'] == '28') {
                return $this->getRetData(CURL_ERROR_NO, '系统繁忙，请稍后再试！', ['timeout' => 1]);
            } else {
                return $this->getRetData(CURL_ERROR_NO, '系统繁忙，请稍后再试！', ['timeout' => 0]);
            }
        }
        $res = $res['data'];

        //curl请求paas正常，但是paas调mrms超时
        if ($res["ret"] == '-99999') {
            return $this->getRetData('-99999', '系统繁忙，请稍后再试[' . __LINE__ . ']！', ['timeout' => '1']);
        }

        $rtnData['timeout'] = 0;
        $rtnData['sPaasSerial'] = $res['sSerial'];

        if ($res['ret'] != 0 || $res['data']['iRet'] != 0) {
            $iRet = $res['ret'] != 0 ? $res['ret'] : $res['data']['iRet'];
            return $this->getRetData($iRet, '系统繁忙，请稍后再试！', ['timeout' => '0']);
        } else {
            $rtnData['data'] = [
                'iPackageGroupId' => $res['data']['iPackageGroupId'],
                'iPackageId' => $res['data']['iPackageId'],
                'sPackageName' => $res['data']['sPackageName'],
                'iPackageNum' => $res['data']['iPackageNum'],
                'sPackageCDkey' => $res['data']['sPackageCDkey'],
                'dTimeNow' => $res['data']['dTimeNow'],
            ];
            $rtnData['originalData'] = $res['data'];
            return $this->getRetData(0, 'success', $rtnData);
        }
    }

    /**
     * 扣除积分+发货（事务）
     *
     * @param array $lotteryParam 礼包和角色信息
     * [
     *      'MRMSID' =>'【必填】礼包单号'
     *      'iPackageGroupId' =>'【选填】（iPackageGroupId和iPackageGroupIdList二选一）礼包组ID',
     *      'iPackageGroupIdList' => '【选填】（iPackageGroupId和iPackageGroupIdList二选一）礼包组连抽信息,格式：礼包组ID1,发送数量:抽奖次数@@礼包组ID2,发送数量:抽奖次数@@...',
     *      'iPackageNum' => '【选填】 礼包组数量，默认1',
     *      'sGameOpenid' => '【选填】游戏openid(默认取当前登录账号的openid)，给非当前登录用户的角色发货时传递该值',
     *      'area' =>'【必填】服务器ID（或者手游渠道：手Q、微信)',
     *      'platId' =>'【如果业务区分平台则必填，否则选填】手机操作系统（iOS：0、安卓：1）',
     *      'partition' =>'【如果业务区分区服则必填，否则选填】小区ID',
     *      'roleId' =>'【必填】角色ID',
     *      'roleName' =>'【选填】角色昵称，编码方式：urlencode，编码：utf8',
     *      'checkparam' =>'【必填】角色信息，可以通过Role\getRoleInfo()函数获取',
     *      'checkstr' =>'【必填】角色签名，可以通过Role\getRoleInfo()函数获取',
     *]
     * @param array $pointParam 积分信息
     * [
     *      'iPointId' => '积分ID，多个积分用#间隔开',
     *      'iPointAmount' =>'与积分ID对应要扣除的积分数量，多个数量之间用#间隔',
     *      'iPointType' => '积分账号类型：0-openid（默认），1-openid+area，2-openid+area+roleId，3-openid+paltId，4-openid+area+partition'
     * ]
     *
     * @return array 抽奖结果信息
     * [
     *      'iRet'=>'=0，请求成功，!=0 请求失败',
     *      'sMsg'=>'系统消息',
     *      'data' => [
     *          'iPackageGroupId'=>'成功发货的礼包组ID',
     *          'iPackageId'=>'成功发货的礼包ID',
     *          'sPackageName'=>'成功发货的礼包名称',
     *          'iPackageNum'=>'成功发货的礼包数量',
     *          'sPackageCDkey'=>'CDK',
     *          'dTimeNow' =>'成功发货的时间'
     *      ],
     *      'originalData' =>[],   //发货接口返回的全部数据
     * ]
     */
    public function lotteryPointTrans($lotteryParam, $pointParam)
    {
        if (!isset($lotteryParam['iPackageNum'])) {
            $lotteryParam['iPackageNum'] = 1;
        }

        $checkRet = $this->checkLotteryParam($lotteryParam);
        if ($checkRet['iRet'] != '0') {
            return $checkRet;
        }

        //暂存箱发货
        if ($this->sendType === 1) {
            $lotteryParam['iSendType'] = '1';
        }

        if (empty($pointParam)) {
            return $this->getRetData('-1000615', '需要扣除的积分信息不能为空！', ['timeout' => '0']);
        }

        if (!isset($pointParam['iPointId']) || !preg_match("/^(\d+)(#\d+)*$/", $pointParam['iPointId'])) {
            return $this->getRetData('-1000616', '需要扣除的积分ID错误！', ['timeout' => '0']);
        }

        //默认扣除1个积分
        if (!isset($pointParam['iPointAmount'])) {
            $idNum = substr_count($pointParam['iPointId'], '#');
            $pointArr = array_fill(0, $idNum + 1, 1);
            $pointParam['iPointAmount'] = implode('#', $pointArr);
        }

        if (!preg_match("/^(\d+)(#\d+)*$/", $pointParam['iPointAmount'])) {
            return $this->getRetData('-1000617', '需要扣除的积分数量错误！', ['timeout' => '0']);
        }

        if (substr_count($pointParam['iPointId'], '#') != substr_count($pointParam['iPointAmount'], '#')) {
            return ['ret' => '-1000634', 'msg' => '需要扣除的积分Id和扣除数量不匹配', 'data' => []];
        }

        if (!isset($pointParam['iPointType'])) {
            $pointParam['iPointType'] = '0';
        }

        if (!in_array($pointParam['iPointType'], ['0', '1', '2', '3', '4'])) {
            return $this->getRetData('-1000618', '需要扣除的积分账号类型错误！', ['timeout' => '0']);
        }

        if ($pointParam['iPointType'] == '1' && !isset($lotteryParam['area'])) {
            return $this->getRetData('-1000619', '积分账号类型iPointType=1时，渠道（area）必须传！', ['timeout' => '0']);
        }

        if ($pointParam['iPointType'] == '2' && (!isset($lotteryParam['area']) || !isset($lotteryParam['roleId']))) {
            return $this->getRetData('-1000620', '积分账号类型iPointType=2时，渠道（area）和角色ID（roleId）必须传！', ['timeout' => '0']);
        }

        if ($pointParam['iPointType'] == '3' && !isset($lotteryParam['platId'])) {
            return $this->getRetData('-1000629', '积分账号类型iPointType=3时，平台（platId）必须传！', ['timeout' => '0']);
        }

        if ($pointParam['iPointType'] == '4' && (!isset($lotteryParam['area']) || !isset($lotteryParam['partition']))) {
            return $this->getRetData('-1000639', '积分账号类型iPointType=4时，渠道（area）区服（partition）必须传！', ['timeout' => '0']);
        }

        $paasParam = array_merge($lotteryParam, $pointParam);
        //组合URL
        $url = $this->getPaasRequestUrl('lottery.trans', $paasParam);

        $res = $this->http->get($url);
        recordLog("lottery point trans paas result：" . var_export($res, true), __FILE__, __LINE__);

        if ($res['ret'] != 0) {
            $this->tglogReport('框架请求ULink-Paas出现异常，curl_errno：' . $res['ret'] . '，curl_error：' . $res['msg'], 'lottery.trans');
            if ($res['ret'] == '28') {
                return $this->getRetData(CURL_ERROR_NO, '系统繁忙，请稍后再试！', ['timeout' => '1']);
            } else {
                return $this->getRetData(CURL_ERROR_NO, '系统繁忙，请稍后再试！', ['timeout' => '0']);
            }
        }

        $res = $res['data'];
        //curl请求paas正常，但是paas调mrms超时
        if ($res["ret"] == '-99999') {
            return $this->getRetData('-99999', '系统繁忙，请稍后再试[' . __LINE__ . ']！', ['timeout' => '1']);
        }

        $rtnData['timeout'] = '0';
        $rtnData['sPaasSerial'] = $res['sSerial'];

        if ($res['ret'] != 0 || $res['data']['iRet'] != 0) {
            $iRet = $res['ret'] != 0 ? $res['ret'] : $res['data']['iRet'];
            return $this->getRetData($iRet, '系统繁忙，请稍后再试！', ['timeout' => '0']);
        } else {
            $rtnData['data'] = [
                'iPackageGroupId' => $res['data']['iPackageGroupId'],
                'iPackageId' => $res['data']['iPackageId'],
                'sPackageName' => $res['data']['sPackageName'],
                'iPackageNum' => $res['data']['iPackageNum'],
                'sPackageCDkey' => $res['data']['sPackageCDkey'],
                'dTimeNow' => $res['data']['dTimeNow'],
            ];
            $rtnData['originalData'] = $res['data'];
            return $this->getRetData(0, 'success', $rtnData);
        }
    }

    /**
     * 扣除资格积分+发货（事务）,应用程序不需要进行资格控制以及资格回滚等，每次发货，直接请求该接口即可
     *
     * @param array $lotteryParam 礼包和角色信息
     * [
     *      'MRMSID' =>'【必填】礼包单号'
     *      'iPackageGroupId' =>'【选填】（iPackageGroupId和iPackageGroupIdList二选一）礼包组ID',
     *      'iPackageGroupIdList' => '【选填】（iPackageGroupId和iPackageGroupIdList二选一）礼包组连抽信息,格式：礼包组ID1,发送数量:抽奖次数@@礼包组ID2,发送数量:抽奖次数@@...',
     *      'iPackageNum' => '【选填】 礼包组数量，默认1',
     *      'sGameOpenid' => '【选填】游戏openid(默认取当前登录账号的openid)，给非当前登录用户的角色发货时传递该值',
     *      'area' =>'【必填】服务器ID（或者手游渠道：手Q、微信)',
     *      'platId' =>'【如果业务区分平台则必填，否则选填】手机操作系统（iOS：0、安卓：1）',
     *      'partition' =>'【如果业务区分区服则必填，否则选填】小区ID',
     *      'roleId' =>'【必填】角色ID',
     *      'roleName' =>'【选填】角色昵称，编码方式：urlencode，编码：utf8',
     *      'checkparam' =>'【必填】角色信息，可以通过Role\getRoleInfo()函数获取',
     *      'checkstr' =>'【必填】角色签名，可以通过Role\getRoleInfo()函数获取',
     *]
     * @param array $qualParam  资格信息
     * [
     *      'qualKey' => '【必填】用于资格控制的key(必须唯一)，不要加openid，paas接口会自动加上openid',
     *      'limitNum' =>'【必填】周期内可以获得的总资格',
     *      'limitType' => '【必填】A|D|Z|M  A-整个活动期间，D-以天为周期性资格，Z-以自然周为周期性资格，M-以自然月为周期性资格'
     *      'cycleNum' =>'【limitType参数不为A时必填，为A时该值无意义】limitType对应的周期长度'
     *      'usePerTime' => '【选填】每次使用需要扣除的数量，默认扣除1',
     * ]
     *
     * 例如：
     * $qualParam['qualKey'=>'test1', 'limitNum'=>'1', 'limitType'=>'A'] 表示整个活动期间获得1次资格
     * $qualParam['qualKey'=>'test1', 'limitNum'=>'1', 'limitType'=>'D', 'cycleNum'=>'2'] 表示以每2天为一个周期，每个周期（每2天）获得1次资格
     * $qualParam['qualKey'=>'test1', 'limitNum'=>'2', 'limitType'=>'D', 'cycleNum'=>'1'] 表示以每1天为一个周期，每个周期（每1天）获得2次资格
     * $qualParam['qualKey'=>'test1', 'limitNum'=>'2', 'limitType'=>'Z', 'cycleNum'=>'1'] 表示以每1自然周为一个周期，每个周期（每1个自然周）获得2次资格
     * $qualParam['qualKey'=>'test1', 'limitNum'=>'1', 'limitType'=>'M', 'cycleNum'=>'3'] 表示以每3自然月为一个周期，每个周期（每3个自然月）获得1次资格
     *
     * @param array $pointParam  积分信息
     * [
     *      'iPointId' => '积分ID，多个积分用#间隔开',
     *      'iPointAmount' =>'与积分ID对应要扣除的积分数量，多个数量之间用#间隔',
     *      'iPointType' => '积分账号类型：0-openid（默认），1-openid+area，2-openid+area+roleId，3-openid+paltId，4-openid+area+partition'
     * ]
     *
     * @param array $pubQualParam  【选填】公共资格信息，默认空数组
     * [
     *      'qualKey' => '【必填】用于资格控制的key(必须唯一)，不要加openid，paas接口会自动加上openid',
     *      'limitNum' =>'【必填】周期内可以获得的总资格',
     *      'limitType' => '【必填】A|D|Z|M  A-整个活动期间，D-以天为周期性资格，Z-以自然周为周期性资格，M-以自然月为周期性资格'
     *      'cycleNum' =>'【limitType参数不为A时必填，为A时该值无意义】limitType对应的周期长度'
     *      'usePerTime' => '【选填】每次使用需要扣除的数量，默认扣除1',
     * ]
     *
     * 使用场景：
     * 抽奖限制每天1次，活动期间总限制5次。就可以通过$pubQualParam参数来控制
     * $qualParam = ['qualKey'=>'lottery_login_day', 'limitNum'=>'1', 'limitType'=>'D', 'cycleNum'=>'1']
     * $pubQualParam = ['qualKey'=>'lottery_login_total', 'limitNum'=>'5', 'limitType'=>'A']
     *
     *
     * @return array 抽奖结果信息
     * [
     *      'iRet'=>'=0，请求成功，!=0 请求失败',
     *      'sMsg'=>'系统消息',
     *      'data' => [
     *          'iPackageGroupId'=>'成功发货的礼包组ID',
     *          'iPackageId'=>'成功发货的礼包ID',
     *          'sPackageName'=>'成功发货的礼包名称',
     *          'iPackageNum'=>'成功发货的礼包数量',
     *          'sPackageCDkey'=>'CDK',
     *          'dTimeNow' =>'成功发货的时间'
     *      ]
     * ]
     */
    public function lotteryQualAndPointTrans($lotteryParam, $qualParam = [], $pointParam = [], $pubQualParam = [])
    {
        if (!is_array($lotteryParam) || !is_array($qualParam) || !is_array($pointParam) || !is_array($pubQualParam)) {
            return $this->getRetData('-1000800', '参数错误！', ['timeout' => 0]);
        }
        if (empty($qualParam) && empty($pointParam) && empty($pubQualParam)) {
            return $this->getRetData('-1000801', '积分参数和资格参数不能同时为空！', ['timeout' => 0]);
        }

        if (!isset($lotteryParam['iPackageNum'])) {
            $lotteryParam['iPackageNum'] = 1;
        }
        $checkRet = $this->checkLotteryParam($lotteryParam);
        if ($checkRet['iRet'] != '0') {
            return $checkRet;
        }

        if (!isset($qualParam['qualKey']) || $qualParam['qualKey'] == '') {
            return $this->getRetData('-1000802', '资格key不能为空！', ['timeout' => 0]);
        }

        if (!isset($qualParam['usePerTime']) || empty($qualParam['usePerTime'])) {
            $qualParam['usePerTime'] = 1;
        }
        if (!in_array($qualParam['limitType'], array('A', 'D', 'W', 'M', 'Z'))) {
            recordLog("limitType error：value=" . $qualParam['limitType'], __FILE__, __LINE__, LP_ERROR);
            return $this->getRetData('-1000803', '资格类型错误！', ['timeout' => 0]);
        }
        if ($qualParam['usePerTime'] > $qualParam['limitNum']) {
            recordLog("usePerTime should be smaller than limitNum!", __FILE__, __LINE__, LP_ERROR);
            return $this->getRetData('-1000804', '需要扣除的资格数错误！', ['timeout' => 0]);
        }

        $lotteryParam['sQualKey'] = $qualParam['qualKey'];

        if ($qualParam['limitType'] == 'A') {
            $lotteryParam['sLimitType'] = '1';
        } else {
            if (!isset($qualParam['cycleNum']) || !preg_match('/^[1-9]+\d*$/', $qualParam['cycleNum'])) {
                return $this->getRetData('-1000805', '周期资格数错误！', ['timeout' => 0]);
            }
            $lotteryParam['sLimitType'] = '2_' . $qualParam['limitType'] . '_' . $qualParam['cycleNum'];
        }

        $lotteryParam['iLimitNum'] = $qualParam['limitNum'];
        $lotteryParam['iUsePerTime'] = $qualParam['usePerTime'];

        if (!isset($lotteryParam['iPackageNum'])) {
            $lotteryParam['iPackageNum'] = 1;
        }

        if (isset($pubQualParam['qualKey']) && $pubQualParam['qualKey'] != '') {

            if ($pubQualParam['qualKey'] == $qualParam['qualKey']) {
                recordLog("public qualkey and private qualkey cannot be the same!", __FILE__, __LINE__, LP_ERROR);
                return $this->getRetData('-1000806', '公有资格key和私有资格key不能相同！', ['timeout' => 0]);
            }

            if (!preg_match('/^[1-9]\d*$/', $pubQualParam['limitNum'])) {
                recordLog("public qual limitNum error：value=" . $pubQualParam['limitNum'], __FILE__, __LINE__, LP_ERROR);
                return $this->getRetData('-1000807', '公有资格总数错误！', ['timeout' => 0]);
            }

            if (!isset($pubQualParam['usePerTime']) || $pubQualParam['usePerTime'] == '') {
                $pubQualParam['usePerTime'] = 1;
            }
            if (!preg_match('/^[1-9]\d*$/', $pubQualParam['usePerTime'])) {
                recordLog("public qual usePerTime error：value=" . $pubQualParam['usePerTime'], __FILE__, __LINE__, LP_ERROR);
                return $this->getRetData('-1000808', '每次扣除的公有资格数错误！', ['timeout' => 0]);
            }

            if (!in_array($pubQualParam['limitType'], array('A', 'D', 'W', 'M', 'Z'))) {
                recordLog("public qual limitType error：value=" . $pubQualParam['limitType'], __FILE__, __LINE__, LP_ERROR);
                return $this->getRetData('-1000809', '公有资格类型错误！', ['timeout' => 0]);
            }

            if ($pubQualParam['usePerTime'] > $pubQualParam['limitNum']) {
                recordLog("public qual usePerTime should be smaller than limitNum!", __FILE__, __LINE__, LP_ERROR);
                return $this->getRetData('-1000810', '需要扣除的公有资格数错误！', ['timeout' => 0]);
            }

            $lotteryParam['sPubQualKey'] = $pubQualParam['qualKey'];

            if ($pubQualParam['limitType'] == 'A') {
                $lotteryParam['sPubLimitType'] = '1';
            } else {
                if (!isset($pubQualParam['cycleNum']) || !preg_match('/^[1-9]+\d*$/', $pubQualParam['cycleNum'])) {
                    recordLog("public qual cycleNum error：value=" . $pubQualParam['cycleNum'], __FILE__, __LINE__, LP_ERROR);
                    return $this->getRetData('-1000811', '周期公有资格数错误！', ['timeout' => 0]);
                }
                $lotteryParam['sPubLimitType'] = '2_' . $pubQualParam['limitType'] . '_' . $pubQualParam['cycleNum'];
            }

            $lotteryParam['iPubLimitNum'] = $pubQualParam['limitNum'];
            $lotteryParam['iPubUsePerTime'] = $pubQualParam['usePerTime'];
        }

        //积分相关参数检查
        if (!isset($pointParam['iPointId']) || !preg_match("/^(\d+)(#\d+)*$/", $pointParam['iPointId'])) {
            return $this->getRetData('-1000812', '需要扣除的积分ID错误！', ['timeout' => '0']);
        }
        //默认扣除1个积分
        if (!isset($pointParam['iPointAmount'])) {
            $idNum = substr_count($pointParam['iPointId'], '#');
            $pointArr = array_fill(0, $idNum + 1, 1);
            $pointParam['iPointAmount'] = implode('#', $pointArr);
        }

        if (!preg_match("/^(\d+)(#\d+)*$/", $pointParam['iPointAmount'])) {
            return $this->getRetData('-1000813', '需要扣除的积分数量错误！', ['timeout' => '0']);
        }

        if (substr_count($pointParam['iPointId'], '#') != substr_count($pointParam['iPointAmount'], '#')) {
            return ['ret' => '-1000814', 'msg' => '需要扣除的积分Id和扣除数量不匹配', 'data' => []];
        }

        if (!isset($pointParam['iPointType'])) {
            $pointParam['iPointType'] = '0';
        }

        if (!in_array($pointParam['iPointType'], ['0', '1', '2', '3', '4'])) {
            return $this->getRetData('-1000815', '需要扣除的积分账号类型错误！', ['timeout' => '0']);
        }

        if ($pointParam['iPointType'] == '1' && !isset($lotteryParam['area'])) {
            return $this->getRetData('-1000816', '积分账号类型iPointType=1时，渠道（area）必须传！', ['timeout' => '0']);
        }

        if ($pointParam['iPointType'] == '2' && (!isset($lotteryParam['area']) || !isset($lotteryParam['roleId']))) {
            return $this->getRetData('-1000817', '积分账号类型iPointType=2时，渠道（area）和角色ID（roleId）必须传！', ['timeout' => '0']);
        }

        if ($pointParam['iPointType'] == '3' && !isset($lotteryParam['platId'])) {
            return $this->getRetData('-1000818', '积分账号类型iPointType=3时，平台（platId）必须传！', ['timeout' => '0']);
        }

        if ($pointParam['iPointType'] == '4' && (!isset($lotteryParam['area']) || !isset($lotteryParam['partition']))) {
            return $this->getRetData('-1000819', '积分账号类型iPointType=4时，渠道（area）区服（partition）必须传！', ['timeout' => '0']);
        }

        $lotteryParam = array_merge($lotteryParam, $pointParam);

        //组合URL
        $url = $this->getPaasRequestUrl('lottery.trans', $lotteryParam);
        $res = $this->http->get($url);
        recordLog("lottery qual trans paas result：" . var_export($res, true), __FILE__, __LINE__);

        if ($res['ret'] != 0) {
            $this->tglogReport('框架请求ULink-Paas出现异常，curl_errno：' . $res['ret'] . '，curl_error：' . $res['msg'], 'lottery.trans');
            if ($res['ret'] == '28') {
                return $this->getRetData(CURL_ERROR_NO, '系统繁忙，请稍后再试！', ['timeout' => 1]);
            } else {
                return $this->getRetData(CURL_ERROR_NO, '系统繁忙，请稍后再试！', ['timeout' => 0]);
            }
        }
        $res = $res['data'];

        //curl请求paas正常，但是paas调mrms超时
        if ($res["ret"] == '-99999') {
            return $this->getRetData('-99999', '系统繁忙，请稍后再试[' . __LINE__ . ']！', ['timeout' => '1']);
        }

        $rtnData['timeout'] = 0;
        $rtnData['sPaasSerial'] = $res['sSerial'];

        if ($res['ret'] != 0 || $res['data']['iRet'] != 0) {
            $iRet = $res['ret'] != 0 ? $res['ret'] : $res['data']['iRet'];
            return $this->getRetData($iRet, '系统繁忙，请稍后再试！', ['timeout' => '0']);
        } else {
            $rtnData['data'] = [
                'iPackageGroupId' => $res['data']['iPackageGroupId'],
                'iPackageId' => $res['data']['iPackageId'],
                'sPackageName' => $res['data']['sPackageName'],
                'iPackageNum' => $res['data']['iPackageNum'],
                'sPackageCDkey' => $res['data']['sPackageCDkey'],
                'dTimeNow' => $res['data']['dTimeNow'],
            ];
            return $this->getRetData(0, 'success', $rtnData);
        }
    }

    /**
     * 查询抽奖周期礼包剩余量
     * @param string $mrmsId【必填】 礼包单号
     * @param int $iPackageId【必填】 礼包ID
     * @param int $iQueryQQLeft【选填】 1-表示查询单q限量，0-表示总限量
     * @return array
     * [
     *      'iRet' => '=0，请求成功，!=0 请求失败',
     *      'sMsg' => '系统消息',
     *      'sPaasSerial' => 'paas接口流水号'
     *      'data' => [
     *          '$iPackageId'=> [
     *              'iDayLeft' => '日剩余量',
     *              'iDayTotal' => '日总量',
     *              'iWeekLeft' => '周剩余量',
     *              'iWeekTotal' => '周总量',
     *              'iMonthLeft' => '月剩余量',
     *              'iMonthTotal' => '月总量',
     *              'iLeft' => '总剩余量',
     *              'iTotal' => '总量',
     *          ]
     *      ]
     * ]
     */
    public function getLotteryLimit($mrmsId, $iPackageId, $iQueryQQLeft = 0)
    {
        //获取iModuleId
        $arr = explode("-", $mrmsId);
        if (count($arr) == 3 && $arr[0] == "IEGAMS") {
            $iModuleId = $arr[2];
        } else {
            return $this->getRetData('-1000621', '礼包单号错误！');
        }

        $paasParam = ['iModuleId' => intval($iModuleId), 'iPackageId' => intval($iPackageId), 'iQueryQQLeft' => intval($iQueryQQLeft)];
        //组合URL
        $url = $this->getPaasRequestUrl('resource.lotterylimitsvr', $paasParam);
        $res = $this->http->get($url);
        recordLog('查询礼包限量接口返回数据：' . var_export($res, true), __FILE__, __LINE__);

        if ($res['ret'] != 0) {
            $this->tglogReport('框架请求ULink-Paas出现异常，curl_errno：' . $res['ret'] . '，curl_error：' . $res['msg'], 'resource.lotterylimitsvr');
            return $this->getRetData(CURL_ERROR_NO, '系统繁忙，请稍后再试！');
        }
        $res = $res['data'];

        recordLog("lotterylimit paas result：" . var_export($res, true), __FILE__, __LINE__);

        $rtnData['sPaasSerial'] = $res['sSerial'];

        if ($res['ret'] != 0 || $res['data']['iRet'] != 0) {
            $iRet = $res['ret'] != 0 ? $res['ret'] : $res['data']['iRet'];
            return $this->getRetData($iRet, '系统繁忙，请稍后再试！');
        } else {
            $rtnData['data'][$iPackageId] = $res['data']['jData'];
            return $this->getRetData(0, 'success', $rtnData);
        }
    }

    /**
     * 检查抽奖接口必须传递参数有效性
     */
    private function checkLotteryParam($lotteryParam)
    {
        if (!Validate::checkMRMSID($lotteryParam['MRMSID'])) {
            return $this->getRetData('-1000622', '礼包单号不能为空！');
        }

        //$lotteryParam['iPackageGroupId'] 和 $lotteryParam['iPackageGroupIdList'] 二者只能传一个
        if (isset($lotteryParam['iPackageGroupId']) && isset($lotteryParam['iPackageGroupIdList'])) {
            return $this->getRetData('-1000623', '礼包组ID和礼包组连抽信息不能同时传！');
        }

        //$lotteryParam['iPackageGroupId'] 和 $lotteryParam['iPackageGroupIdList'] 不能都为空
        if (!isset($lotteryParam['iPackageGroupId']) && !isset($lotteryParam['iPackageGroupIdList'])) {
            return $this->getRetData('-1000624', '礼包组ID和礼包组连抽信息必选有一个参数传递值！');
        }

        if (isset($lotteryParam['iPackageGroupIdList']) && !preg_match("/^((\d+)(,\d+)?:(\d+)(@@)?)*(\d+)(,\d+)?:(\d+)$/", $lotteryParam['iPackageGroupIdList'])) {
            return $this->getRetData('-1000625', '连抽礼包组格式错误！');
        }

        if (isset($lotteryParam['iPackageGroupId']) && !Validate::checkNaturalNum($lotteryParam['iPackageGroupId'])) {
            return $this->getRetData('-1000626', '礼包组ID错误！');
        }

        if (!Validate::checkNaturalNum($lotteryParam['iPackageNum'])) {
            return $this->getRetData('-1000627', '礼包领取数量错误！');
        }

        //角色参数检查
        $result = [];
        $roleCheck = Validate::checkRoleData($lotteryParam, $result);
        return $this->getRetData($result['iRet'], $result['sMsg']);
    }

    /**
     * 查询礼包单的配置
     * @param string $mrmsId 要查询配置的礼包单号
     * @param int 【选填】$packageGroupId 要查询配置的礼包组ID，如果不传该参数，则返回礼包单中所有礼包组的配置信息，如果传入该参数，则返回对应的礼包组的配置信息
     * @param int 【选填】$packageId 要查询配置的礼包ID，如果传入改参数，$packageGroupId参数的值无效。
     * @return array
     * 例如：
     * [
     *      'iRet' => '0',
     *      'sMsg' => 'success',
     *      'data' = >[
     *          '1118210' => [  //礼包组ID
     *              '1715225' => [  //礼包ID
     *                  //礼包中每个道具对应的一个数组，有多个道具，则是多个数组，数组下标从0开始
     *                  [
     *                      'iItemCode': "3",
     *                      'iItemCount': "1",
     *                      'iItemId': "2364583",
     *                      'iPackageGroupId': "1118210",
     *                      'iPackageId': "1715225",
     *                      'sExtend': "",
     *                      'sGoodsPic': "",
     *                      'sGoodsPicBig': "",
     *                      'sItemName': "体育鹅鹅币",
     *                      'sItemValue': "1",
     *                      'sPackageGroupGoodsPic': "",
     *                      'sPackageGroupName': "1鹅币",
     *                      'sPackageName': "1鹅币",
     *                      'sValidPeriod': "",
     *              ]
     *          ]
     *      ]
     * ]
     * ]
     */
    public function getMRMSCfg(string $mrmsId, int $packageGroupId = 0, int $packageId = 0)
    {
        if (!Validate::checkMRMSID($mrmsId)) {
            return $this->getRetData('-1', '礼包单号错误！');
        }

        if ($packageGroupId != 0 && !Validate::checkNaturalNum($packageGroupId)) {
            return $this->getRetData('-2', '礼包组ID错误！');
        }

        if ($packageId != 0 && !Validate::checkNaturalNum($packageId)) {
            return $this->getRetData('-3', '礼包ID错误！');
        }

        $paasParam = [
            'MRMSID' => $mrmsId,
            'iPackageGroupId' => $packageGroupId,
            'iPackageId' => $packageId,
        ];

        //组合URL
        $url = $this->getPaasRequestUrl('resource.lotterycfg', $paasParam);
        $res = $this->http->get($url);
        recordLog('查询礼包单配置信息接口返回数据：' . var_export($res, true), __FILE__, __LINE__);

        if ($res['ret'] != 0) {
            $this->tglogReport('框架请求ULink-Paas出现异常，curl_errno：' . $res['ret'] . '，curl_error：' . $res['msg'], 'resource.lotterycfg');
            return $this->getRetData(CURL_ERROR_NO, '系统繁忙，请稍后再试！');
        }

        $res = $res['data'];

        if ($res['ret'] != 0) {
            return $this->getRetData($res['ret'], $res['msg']);
        } else {
            return $this->getRetData(0, 'success', ['data' => $res['data']]);
        }
    }

    /**
     *  发货失败，将相关信息记录到db
     */
    private function saveLotteryLog($status, $log, $lotteryInfo)
    {
        if (ENV == 'pro') {
            $insData = [];

            if (!Validate::checkNaturalNum(Request::param('iActId'))) {
                return false;
            }

            if (!Validate::checkUin(Request::param('openid'))) {
                return false;
            }

            if (!preg_match('/^AMS-[a-zA-Z0-9-_]{1,15}-\d{10}-[a-zA-Z\d]{6,10}-\d+-\d+$/', Request::getParam('sAmsSerial'))) {
                return false;
            }

            $insData['openid'] = Request::param('openid');
            $insData['area'] = isset($lotteryInfo['sArea']) ? $lotteryInfo['sArea'] : '-1';
            $insData['platid'] = isset($lotteryInfo['sPlatId']) ? $lotteryInfo['sPlatId'] : '-1';
            $insData['partition'] = isset($lotteryInfo['sPartition']) ? $lotteryInfo['sPartition'] : '-1';
            $insData['roleid'] = isset($lotteryInfo['sRoleId']) ? $lotteryInfo['sRoleId'] : '';
            $insData['rolename'] = isset($lotteryInfo['sRoleName']) ? urlencode($lotteryInfo['sRoleName']) : '';
            $insData['addTime'] = date('Y-m-d H:i:s');
            $insData['status'] = $status;
            $insData['num'] = '0';
            $insData['log'] = $log;
            $insData['sSerial'] = Request::getParam('sAmsSerial');

            $db = new Query();
            $db->table('tbMRMSFail')->insert($insData);
        }
    }
}
